package com.lry.sso.gateway.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lry.sso.common.util.StringHelper;
import com.lry.sso.gateway.bean.RequestWrapper;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.exception.ZuulException;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * 请求与响应处理
 *
 * @author 李瑞益
 * @date 2019/12/8
 */
@Component
public class RequestFilter extends ZuulFilter {

    private static final Logger logger = LoggerFactory.getLogger(RequestFilter.class);

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return FilterConstants.PRE_DECORATION_FILTER_ORDER - 1;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @SneakyThrows
    @Override
    public Object run() throws ZuulException {
        HttpServletRequest request = com.netflix.zuul.context.RequestContext.getCurrentContext().getRequest();
        logger.info("请求路径：{}", request.getRequestURI());

        Map<String, String[]> parameterMap = request.getParameterMap();
        String body = JSON.toJSONString(parameterMap);
        logger.info("路径参数：{}", body);
        RequestWrapper rw = new RequestWrapper(request);
        String json = rw.getBody();
        if (!StringUtils.isEmpty(json)) {
            logger.info("请求体参数：{}", json);
            JSONObject jsonObject = JSON.parseObject(json);
            //对string类型的参数进行trim操作；
            for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
                this.paramHandler(entry);
            }
            logger.info("处理完后的请求体：{}", jsonObject.toJSONString());
            rw.setBody(jsonObject.toJSONString());
        }
        com.netflix.zuul.context.RequestContext.getCurrentContext().setRequest(rw);
        return null;
    }

    /**
     * 处理请求参数
     *
     * @param sourceEntry JSON化参数的entry
     */
    private void paramHandler(Map.Entry<String, Object> sourceEntry) {
        Object obj = sourceEntry.getValue();
        if (obj instanceof Map) {
            for (Map.Entry<String, Object> entry : ((Map<String, Object>) obj).entrySet()) {
                this.paramHandler(entry);
            }
        } else if (isNoNullStringClass(obj)) {
            sourceEntry.setValue(((String) obj).trim());
//        } else if (obj instanceof JSONArray[]) {
//            sourceEntry.setValue(jsonArrays((JSONArray[])obj));
        } else if (obj instanceof JSONArray) {
            sourceEntry.setValue(jsonArrayHandler((JSONArray) obj));
        }
    }

    /**
     * JSONArray[]
     *
     * @param values
     */
//    private JSONArray[] jsonArrays(JSONArray[] values) {
//        JSONArray[] newValue = new JSONArray[values.length];
//        for (int i = 0; i < values.length; i++) {
//            for (int j = 0; j < values[i].size(); j++) {
//                newValue[i].set(j,jsonArray(values[i].get(j)));
//                newValue[i] = jsonArray(values[i].get(j));
//            }
//        }
//        return newValue;
//    }

    /**
     * JSONArray
     *
     * @param ja 参数JSONArray
     * @return 处理过的JSONArray
     */
    private JSONArray jsonArrayHandler(JSONArray ja) {
        JSONArray newJa = new JSONArray();
        for (int i = 0; i < ja.size(); i++) {
            if (isNoNullStringClass(ja.get(i))) {
                newJa.add(StringHelper.valueOf(ja.get(i)).trim());
            } else if (ja.get(i) instanceof Map) {
                paramHandler((Map.Entry<String, Object>) ja.get(i));
//            } else if (ja.get(i) instanceof JSONArray[]) {
//                jsonArrays((JSONArray[])ja.get(i));
            } else if (ja.get(i) instanceof JSONArray) {
                newJa.add(jsonArrayHandler((JSONArray) ja.get(i)));
            }
        }
        return newJa;
    }

    /**
     * 判断是否是string类型且 不为空
     *
     * @param object 对象
     * @return true：是string类型，不为空
     */
    private boolean isNoNullStringClass(Object object) {
        return object instanceof String && !StringUtils.isEmpty(object);
    }
}